#include "Scene.h"

#include "SceneSubsystems/SceneSubsystem.h"

#include "Widgets/ViewportWidget.h"

#include "Scene/CameraComponent.h"
#include "Scene/InputComponent.h"

#include "Framework/SceneManager.h"

#include "Physics/Collider/Collider.h"

void RScene::Tick(float DeltaSecons)
{   
    if(!bPlaying)
    {
        return;
    }


    PhysicalScene->Tick(DeltaSecons);

    for(auto& Node: Nodes)
    {
        Node->Tick(DeltaSecons);
    }
    
}


void RScene::Paint(CRenderScene* InRenderSceneData)
{
    for(auto& Node: Nodes)
    {
        Node->Paint(InRenderSceneData);
    }
}

void RScene::AddNode(TSharedObjectPtr<RSceneNode> InNode)
{
    InNode->SetOwner(this);

    if(InNode->IsPlaying())
    {
        InNode->EndPlay();
    }

    Nodes.Add(InNode);

    if(bPlaying)
    {
        InNode->BeginPlay();
    }
}

int64_t RScene::GetNodeNum()
{
    return Nodes.Num();
}

TSharedObjectPtr<RSceneNode> RScene::GetNode(int64_t InNodeIndex)
{
    return Nodes[InNodeIndex];
}

void RScene::PaintCollider(CRenderScene *InRenderSceneData)
{
    for(auto& Node: Nodes)
    {
        for(auto& Collider: Node->GetComponents<RCollider>())
        {
            Collider->PaintCollider(InRenderSceneData);
        }
    }

    //绘制一点光照，避免没有光照的地方看不到
    InRenderSceneData->AddAmbientLight(SColor(0.1,0.1,0.1,1),1);
}


RScene::RScene()
{

    RApplication::GetApplication()->GetSubsystem<RSceneManager>()
        ->Register(this);

    PhysicalScene=NewObject<RPhysicalScene>(this);
}

RScene::~RScene()
{
    bIsDestroying=true;

    RApplication::GetApplication()->GetSubsystem<RSceneManager>()
        ->UnRegister(this);
    
}

void RScene::FirstTimeInitializeObject()
{
    //Create Root Node
    // RootNode=NewObject<RSceneNode>(this);
    // RootNode->SetScene(this);
    // RootNode->SetNodeName(U"Root");

    SubsystemManager=NewObject<RSubsystemManager>(this);
    SubsystemManager->InitializeSubsystems(RSceneSubsystem::StaticClass(),this);
}

void RScene::BeginPlay()
{
    bPlaying=true;

    for(auto& Node: Nodes)
    {
        Node->BeginPlay();
    }

    OnBeginPlay.Broadcast();
}

void RScene::EndPlay()
{
    for(auto& Node: Nodes)
    {
        Node->EndPlay();
    }
    bPlaying=false;
}


RSceneNodePtr RScene::FindNodeByClass(CClass* InClass)
{
    for(auto& Node: Nodes)
    {
        if(Node->IsA(InClass))
        {
            return Node;
        }
    }
    return nullptr;
}
